﻿using DataModels.Dto.WorkOrder;
using DataModels.Entities.Base;
using DataModels.Entities.House;
using DataModels.Entities.WorkOrder;
using DataModels.Enums.WorkOrder;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using SEGIService.SGModel;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection.Emit;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using static DataModels.Enums.GeneralEnum;
using static SEGIService.SGModel.SigeCommunityResult;

namespace SEGIService.Service.Basic.Work
{
    public class SigeWorkService(SqlSugarClient db, ILogger<SigeWorkService> logger, IConfiguration config, IMemoryCache memoryCache) : SEGIBaseService(db)
    {
        private readonly ILogger<SigeWorkService> _logger = logger;
        private readonly IConfiguration _config = config;



        public async Task UpdateWorkordertype()
        {
            var allItems = new List<WorkOrderType>();
            var bodydata = new
            {
                main_segi_community_id = "14911167" //项目ID（真实小区ID）
            };
            var json = await SendSigeWorkOrderRequestAsync("/v2/serviceOrder/queryServiceTypeList", bodydata);

            var result = JsonConvert.DeserializeObject<SigeWorkTypeResponse>(json);

            if (result.Code != "0")
            {
                throw new Exception($"接口返回失败：{result.Message}");
            }

            if (result.Data != null)
            {
                foreach (ServiceItem _ServiceItem in result.Data)
                {
                    WorkOrderType w = new WorkOrderType();
                    w.Name = _ServiceItem.ServiceTypeName;
                    w.ServiceTypeCode = _ServiceItem.ServiceTypeCode;
                    w.ParentServiceTypeCode = "0";
                    w.ParentId = 0;
                    w.WhereToUse = "sige";
                    WorkOrderType wo = db.Insertable(w).ExecuteReturnEntity();

                    string ParentServiceTypeCode = _ServiceItem.ServiceTypeCode;
                    foreach (BusiType _BusiType in _ServiceItem.BusiType)
                    {
                        WorkOrderType w1 = new WorkOrderType();
                        w1.Name = _BusiType.BusiName;
                        w1.ServiceTypeCode = _BusiType.BusiCode;
                        w1.ParentServiceTypeCode = ParentServiceTypeCode;
                        w1.ParentId = wo.Id;
                        w1.WhereToUse = "sige";
                        allItems.Add(w1);
                    }
                }
                db.Insertable(allItems).ExecuteCommand();

            }
        }

        public async Task<string> AddWorkerInfo(SigeCreateWorkOrderInfoRequest bodydata)
        {
            var json = await SendSigeWorkOrderRequestAsync("/v2/serviceOrder/createOrder", bodydata);
            var result = JsonConvert.DeserializeObject<SigeWorkAddTrueResponse>(json);

            if (result.Code != "0")
            {
                return "";
                //throw new Exception($"新增报单接口返回失败：{result.Message}");
            }

            if (result.Data != null)
            {
                return result.Data.serviceOrderId;
            }
            return "";
        }

        /// <summary>
        /// 根据项目UUID获取四格ID
        /// </summary>
        /// <param name="projectsUUID"></param>
        /// <returns></returns>
        protected string GetOrganIdBySIGE(Guid projectsUUID)
        {
            var projects = db.Queryable<Projects>().Where(c => c.UUID == projectsUUID).First();
            return projects.CommunityId;
        }

        // 限制时间：1小时（单位：秒）
        private const int _limitSeconds = 36;// 3600;

        /// <summary>
        /// 校验手机号是否允许调用方法（1小时1次）
        /// </summary>
        /// <param name="phoneNumber">手机号</param>
        /// <returns>true=允许调用，false=已达限制</returns>
        public bool CanCallByPhone(string phoneNumber)
        {
            if (string.IsNullOrWhiteSpace(phoneNumber))
                throw new ArgumentNullException(nameof(phoneNumber), "手机号不能为空");

            // 缓存Key：用固定前缀+手机号，避免与其他缓存冲突
            string cacheKey = $"MethodLimit:Phone:{phoneNumber}";

            // 1. 尝试获取该手机号的最近调用时间
            if (memoryCache.TryGetValue<DateTime>(cacheKey, out var lastCallTime))
            {
                // 2. 计算时间间隔：当前时间 - 最近调用时间
                TimeSpan interval = DateTime.Now - lastCallTime;
                // 间隔 < 1小时：拒绝调用
                if (interval.TotalSeconds < _limitSeconds)
                    return false;
            }

            // 3. 允许调用：更新缓存（设置1小时后过期，避免内存泄漏）
            memoryCache.Set(
                key: cacheKey,
                value: DateTime.Now,
                absoluteExpirationRelativeToNow: TimeSpan.FromSeconds(_limitSeconds)
            );

            return true;
        }
        public async Task UpdateWorkerStatic(string phone)
        {
            // 1. 先校验调用权限
            if (!CanCallByPhone(phone))
                return;

            // 2. 校验通过，执行实际业务逻辑

            var WorkOrderList = db.Queryable<WorkOrderTable>().Where(w => w.Phone == phone).ToList();
            if (WorkOrderList.Count > 0)
            {
                List<WorkOrderHistory> WorkOrderHistorylist = new List<WorkOrderHistory>();

                List<Guid?> ProjectIds = WorkOrderList
                .GroupBy(n => n.ProjectId)
                .Select(g => g.Key).ToList();
                // 查询所有房屋 houseIds  一次最多10个
                foreach (var ProjectId in ProjectIds)
                {
                    var bodyObject = new
                    {
                        main_segi_community_id = GetOrganIdBySIGE((Guid)ProjectId), //项目ID（真实小区ID）
                        contactTel = phone,
                        beginTime = DateTime.Now.AddDays(-15).ToString("yyyy-MM-dd"),
                        endTime = DateTime.Now.ToString("yyyy-MM-dd")
                    };
                    var json = await SendSigeWorkOrderRequestAsync("/v2/serviceOrder/queryServiceOrderByCust", bodyObject);
                    var result = JsonConvert.DeserializeObject<SigeWorkListResponse>(json);

                    if (result.Code != "0")
                    {
                        Console.WriteLine($"四格工单列表接口返回失败：{result.Message}");
                    }

                    if (result.Data == null)
                        return;

                    foreach (OrderItem OrderItem in result.Data.OrderList)
                    {
                        foreach (WorkOrderTable WorkOrderTable in WorkOrderList)
                        {
                            if (WorkOrderTable.OrderNo != OrderItem.ServiceOrderId)
                                continue;

                            Tuple<bool, WorkOrderStatus> wo1 = SigeServiceOrderStateCon(OrderItem.ServiceOrderStateName, WorkOrderTable.Status);
                            if (wo1.Item1)
                            {
                                WorkOrderTable.Status = wo1.Item2;

                                // 工单历史
                                var bodyObjectH = new
                                {
                                    main_segi_community_id = GetOrganIdBySIGE((Guid)ProjectId), //项目ID（真实小区ID）
                                    serviceOrderId = WorkOrderTable.OrderNo
                                };
                                var jsonH = await SendSigeWorkOrderRequestAsync("/v2/serviceOrder/getOrderTrackInfoById", bodyObjectH);
                                var resultH = JsonConvert.DeserializeObject<WorkOrderTrackResponse>(jsonH);

                                if (resultH.Code != "0")
                                {
                                    Console.WriteLine($"四格工单历史接口返回失败：{resultH.Message}");
                                }

                                if (resultH.Data == null)
                                    continue;

                                List<WorkOrderHistory> _WorkOrderRapidHistory = db.Queryable<WorkOrderHistory>().Where(w => w.OrderNo.Contains(WorkOrderTable.OrderNo)).ToList();
                                foreach (var item in resultH.Data)
                                {
                                    if (_WorkOrderRapidHistory.Count > 0)
                                    {
                                        if (_WorkOrderRapidHistory.Where(w1 => w1.OrderNo == item.TrackId).FirstOrDefault() != null)
                                        { continue; }
                                    }

                                    // 记录工单变更历史
                                    WorkOrderHistory history = new()
                                    {
                                        UUID = Guid.NewGuid(), // 为历史记录生成新的UUID
                                        WorkOrderUUID = WorkOrderTable.UUID,
                                        OrderNo = item.TrackId,
                                        HouseUUID = WorkOrderTable.HouseUUID,
                                        Phone = WorkOrderTable.Phone,
                                        Title = WorkOrderTable.Title,
                                        Description = WorkOrderTable.Description,
                                        TypeId = WorkOrderTable.TypeId,
                                        Type = WorkOrderTable.Type,
                                        Priority = WorkOrderTable.Priority,
                                        Status = WorkOrderTable.Status,
                                        ActualResolveTime = WorkOrderTable.ActualResolveTime,
                                        CreateTime = Convert.ToDateTime(item.CreateDate),
                                        UpdateTime = WorkOrderTable.UpdateTime,
                                        CloseTime = WorkOrderTable.CloseTime,
                                        RequesterId = WorkOrderTable.RequesterId,
                                        ProcessorId = WorkOrderTable.ProcessorId,
                                        ProjectId = WorkOrderTable.ProjectId,
                                        SatisfactionScore = WorkOrderTable.SatisfactionScore,
                                        SatisfactionComment = WorkOrderTable.SatisfactionComment,
                                        ReasonForChange = item.TrackName,
                                        Urgent = WorkOrderTable.Urgent
                                    };
                                    WorkOrderHistorylist.Add(history);
                                }
                            }
                        }
                    }
                }
                db.Updateable(WorkOrderList).ExecuteCommand();
                db.Insertable(WorkOrderHistorylist).ExecuteCommand();
            }
        }

        Tuple<bool, WorkOrderStatus> SigeServiceOrderStateCon(string Name, WorkOrderStatus tstatus)
        {
            bool tf = false;
            WorkOrderStatus r = tstatus;
            switch (Name)
            {
                case "待派单":
                    r = WorkOrderStatus.New;
                    break;
                case "待接单":
                    r = WorkOrderStatus.Processing;
                    break;
                case "处理中":
                    r = WorkOrderStatus.Processing;
                    break;
                case "待审核":
                    r = WorkOrderStatus.Processing;
                    break;
                case "结束":
                    r = WorkOrderStatus.Resolved;
                    break;
                case "取消":
                    r = WorkOrderStatus.Cancelled;
                    break;
                case "待评价":
                    r = WorkOrderStatus.WaitingForFeedback;
                    break;
                default:
                    break;
            }
            if (tstatus != r)
                tf = true;
            return Tuple.Create(tf, r);
        }

        /// <summary>
        /// 四格评价工单
        /// </summary>
        /// <param name="bodydata"></param>
        /// <returns></returns>
        public async Task<string> evaluateServiceOrder(object bodydata)
        {
            var json = await SendSigeWorkOrderRequestAsync("/v2/serviceOrder/evaluateServiceOrder", bodydata);
            var result = JsonConvert.DeserializeObject<SigeWorkAddTrueResponse>(json);

            if (result.Code != "0")
            {
                return result.Message;
                //throw new Exception($"新增报单接口返回失败：{result.Message}");
            }

            if (result.Data != null)
            {
                return result.Data.serviceOrderId;
            }
            return "";
        }

        /// <summary>
        /// 四格取消工单
        /// </summary>
        /// <param name="bodydata"></param>
        /// <returns></returns>
        public async Task<string> discontinueOrder(object bodydata)
        {
            var json = await SendSigeWorkOrderRequestAsync("/v2/serviceOrder/discontinueOrder", bodydata);
            var result = JsonConvert.DeserializeObject<SigeWorkAddTrueResponse>(json);

            return result.Message;
        }


        /// <summary>
        /// 发送请求到四格 工单系统 API
        /// </summary>
        /// <param name="urlName"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<string> SendSigeWorkOrderRequestAsync(string urlName, object data)
        {
            var apiUrl = _config["SigeWorkOrderApi:CommunitySyncUrl"];
            var appKey = _config["SigeWorkOrderApi:appKey"];
            var baseCode = _config["SigeWorkOrderApi:baseCode"];
            var secret = _config["SigeWorkOrderApi:secret"];
            string url = apiUrl + urlName;

            string timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
            var bodyObject = new
            {
                appKey,
                requestTime = timestamp,
                requestId = timestamp,
                noncestr = timestamp,
                apiVersion = "",
                data
            };
            return await GetSEGEResponse(url, appKey, baseCode, secret, bodyObject);
        }



        private async Task<string> GetSEGEResponse(string url, string appKey, string baseCode, string secret, object bodyObject)
        {
            // 序列化为 JSON
            string jsonBody = JsonConvert.SerializeObject(bodyObject);

            // 生成签名
            string signature = GenerateSignature(jsonBody, secret);

            using var client = new HttpClient();
            var request = new HttpRequestMessage(HttpMethod.Post, url);

            // 添加请求头
            request.Headers.Add("signature", signature);
            request.Headers.Add("appkey", appKey);
            request.Headers.Add("basecode", baseCode);

            // 设置请求体
            request.Content = new StringContent(jsonBody, Encoding.UTF8, "application/json");

            var response = await client.SendAsync(request);
            return await response.Content.ReadAsStringAsync();
        }

        /// <summary>
        /// 计算签名
        /// </summary>
        /// <param name="jsonBody"></param>
        /// <param name="secretKey"></param>
        /// <returns></returns>
        private string GenerateSignature(string jsonBody, string secretKey)
        {
            string rawString = jsonBody + "|" + secretKey;

            using var md5 = MD5.Create();
            byte[] bytes = Encoding.UTF8.GetBytes(rawString);
            byte[] hash = md5.ComputeHash(bytes);

            StringBuilder sb = new StringBuilder();
            foreach (byte b in hash)
                sb.Append(b.ToString("x2")); // 小写

            return sb.ToString();
        }
    }
}
